package com.cindata

import com.cindata.dictionary.RiskWarningStatusDict
import com.cindata.dictionary.RiskWarningTypeDict
import org.springframework.security.access.annotation.Secured

import java.text.DecimalFormat

import static org.springframework.http.HttpStatus.*
import grails.gorm.transactions.Transactional

@Secured(['permitAll'])
class CommunityController {


    def dataSource
    def apiService
    def scoreApiService

    static allowedMethods = [save: "POST", update: "PUT", delete: "DELETE"]

    def index(Integer max) {
        params.max = Math.min(max ?: 10, 100)
        respond Community.list(params), model:[communityCount: Community.count()]
    }

    def show(Community community) {
        respond community
    }

    def create() {
        respond new Community(params)
    }

    def initDate()
    {
        //查询所有的小区id
        def db = new groovy.sql.Sql(dataSource)
        def sql = "select distinct community_id, d.zone_number, c.district_id from estate c left join area d on c.city_id = d.area_id where c.community_id is not null"
        def list = db.rows(sql).asList()
        println "查找到"+list.size()+"个小区"
        int count = 0
        list.each 
        {
            if(!Community.findByCommunityId(it?.community_id))
            {
                count++
                println "正在处理第"+count+"条数据"
                println it
                println "调用接口"
                //小区详情
                def community = apiService.community(it?.zone_number, it?.community_id)
                println community
                try
                {
                    community = community?.data
                    def communityd = new Community()
                    communityd.city = City.findByZoneNumber(it?.zone_number)
                    communityd.district = District.findById(it?.district_id)
                    communityd.communityName = community?.communityName
                    communityd.communityId = it?.community_id
                    communityd.propertyManagementCompany = community?.propertyManagementCompany
                    communityd.developer = community?.developer
                    communityd.buildYear = community?.buildYear
                    communityd.plotratio = community?.plotratio
                    communityd.residentialType= community?.residentialType
                    communityd.buildingType = community?.buildingType
                    communityd.totalBuildingCount = community?.totalBuildingCount
                    communityd.buildingstructureName = community?.buildingstructureName
                    communityd.totalHouseHoldCount = community?.totalHouseHoldCount
                    communityd.pmfee = community?.pmfee
                    communityd.address = community?.address
                    communityd.buildArea = community?.buildArea
                    communityd.coveringArea = community?.coveringArea
                    communityd.arcgisX =  community?.x? Double.parseDouble(community?.x) : null
                    communityd.arcgisY =  community?.y ? Double.parseDouble(community?.y): null
                    communityd.communityScore = new BigDecimal(getScore(it?.community_id.toString()).split(":")[0])
                    communityd.save(flush:true)
                    db.commit()
                }
                catch (Exception e)
                {
                    e.printStackTrace()
                }
            }
            else
            {
                println it?.community_id+"已存在"
            }
        }
        render "处理完成"
    }


    def getScore(String community_id)
    {
        println "计算小区评分"
        def score = scoreApiService.communityLiquidityScore(community_id)
        //查询权值
        def communityScoreWeight = CommunityScoreWeight.list().get(0)

        def closingWeight = communityScoreWeight.closingWeight
        // 成交率权重
        def listingWeight = communityScoreWeight.listingWeight
        // 挂牌率权重
        def dealAvgDayWeight = communityScoreWeight.dealAvgDayWeight
        // 成交周期权重
        def discountrateWeight = communityScoreWeight.discountrateWeight
        // 折价比权重
        def foreclosureTimesWeight = communityScoreWeight.foreclosureTimesWeight
        // 法拍次数权重

        //小区配套权值
        def ifSchoolZoneScoreWeight = communityScoreWeight.schoolDistrictsWeight
        def communityTrafficScoreWeight = communityScoreWeight.trafficWeight
        def houseAgeScoreWeight = communityScoreWeight.houseAgeWeight
        def communityHospitalScoreWeight = communityScoreWeight.hospitalWeight
        def communityMallScoreWeight = communityScoreWeight.mallWeight
        def communityGreeningrateScoreWeight = communityScoreWeight.afforestationWeight
        def communityPlotratioScoreWeight = communityScoreWeight.ratioWeight
        def communityParkScoreWeight = communityScoreWeight.parkWeight
        def communityPmfeeScoreWeight = communityScoreWeight.propertyFeeWeight
        def communitySupermarketScoreWeight = communityScoreWeight.superMarketWeight
        def communityBankScoreWeight = communityScoreWeight.bankWeight

        def scenicWeight = communityScoreWeight.scenicWeight
        def noisePullutionWeight = communityScoreWeight.noisePullutionWeight
        def airPullutionWeight = communityScoreWeight.airPullutionWeight

        //小区总分
        def liquidWeight = communityScoreWeight.liquidityWeight
        def surroundWeight = communityScoreWeight.assortWeight
        def natureWeight = communityScoreWeight.natureWeight

        //小区配套评分
        def ifSchoolZoneScore = 0
        def communityTrafficScore = 0
        def houseAgeScore = 0
        def communityHospitalScore = 0
        def communityMallScore = 0
        def communityGreeningrateScore = 0
        def communityPlotratioScore = 0
        def communityParkScore = 0
        def communityPmfeeScore = 0
        def communitySupermarketScore = 0
        def communityBankScore = 0

        //流动性评分
        def closingScore = 0
        def dealAvgDayScore = 0
        def listingScore = 0
        def discountrateScore = 0
        def foreclosureTimesScore = 0

        def scenicScore = 0
        def noisePullutionScore = 0
        def airPullutionScore = 0

        //小区配套总分
        def communitySurroundingScore = 0

        //小区流动性总分
        def liquidityScore = 0

        //小区自然总分
        def natureScore = 0

        def scoreArr = []
        def surroudArr = []
        def natureArr = []

        if (score?.closingScore)
        {
            //成交率评分
            closingScore = (score?.closingScore ? score?.closingScore : 0) * closingWeight
            //成交周期评分
            dealAvgDayScore = (score?.dealAverageDayScore ? score?.dealAverageDayScore : 0) * dealAvgDayWeight
            //挂牌率评分
            listingScore = (score?.listingScore ? score?.listingScore : 0) * listingWeight
            //折价比例评分（法拍计算）
            discountrateScore = (score?.discountrateScore ? score?.discountrateScore : 0) * discountrateWeight
            //法拍次数评分
            foreclosureTimesScore = (score?.foreclosureTimesScore ? score?.foreclosureTimesScore : 0) * foreclosureTimesWeight

            ifSchoolZoneScore = (score?.ifSchoolZoneScore ? score?.ifSchoolZoneScore : 0) * ifSchoolZoneScoreWeight
            communityTrafficScore = (score?.communityTrafficScore ? score?.communityTrafficScore : 0) * communityTrafficScoreWeight
            houseAgeScore = (score?.houseAgeScore ? score?.houseAgeScore : 0) * houseAgeScoreWeight
            communityHospitalScore = (score?.communityHospitalScore ? score?.communityHospitalScore : 0) * communityHospitalScoreWeight
            communityMallScore = (score?.communityMallScore ? score?.communityMallScore : 0) * communityMallScoreWeight
            communityGreeningrateScore = (score?.communityGreeningrateScore ? score?.communityGreeningrateScore : 0) * communityGreeningrateScoreWeight
            communityPlotratioScore = (score?.communityPlotratioScore ? score?.communityPlotratioScore : 0) * communityPlotratioScoreWeight
            communityParkScore = (score?.communityParkScore ? score?.communityParkScore : 0) * communityParkScoreWeight
            communityPmfeeScore = (score?.communityPmfeeScore ? score?.communityPmfeeScore : 0) * communityPmfeeScoreWeight
            communitySupermarketScore = (score?.communitySupermarketScore ? score?.communitySupermarketScore : 0) * communitySupermarketScoreWeight
            communityBankScore = (score?.communityBankScore ? score?.communityBankScore : 0) * communityBankScoreWeight

            scenicScore = (score?.communityRecentlyScenicScore ? score?.communityRecentlyScenicScore : 0) * scenicWeight
            noisePullutionScore = (score?.communityRecentlySubwayScore ? score?.communityRecentlySubwayScore : 0) * noisePullutionWeight
            airPullutionScore = (score?.communityRecentlyPollutionScore ? score?.communityRecentlyPollutionScore : 0) * airPullutionWeight

            communitySurroundingScore = ifSchoolZoneScore + communityTrafficScore + houseAgeScore + communityHospitalScore + communityMallScore + communityGreeningrateScore + communityPlotratioScore + communityParkScore + communityPmfeeScore + communitySupermarketScore + communityBankScore

            liquidityScore = closingScore + dealAvgDayScore + listingScore + discountrateScore + foreclosureTimesScore

            natureScore = scenicScore + noisePullutionScore + airPullutionScore

        }
        def communityScore = liquidityScore * liquidWeight + communitySurroundingScore * surroundWeight + natureScore * natureWeight
        return communityScore+":"+liquidityScore
    }

    //计算集中度
    def caluateRatio(Community community,def map){
        println "计算押品集中度"
        //算出该小区押品数量
        def c1 = Estate.countByCommunityId(community?.communityId)
        //该城市所有押品数量 相处
        def c2 =  map.get(community?.city?.id) ? map.get(community?.city?.id) : 0
        println c1+"--"+c2
        def score = 0
        if(c1 && c2){
             score = -1666.7*(c1/c2) + 5.7
        }
        return score
    }

    /**
     * 计算押品集中度
     */
    def calculateConcentration(){

        def db = new groovy.sql.Sql(dataSource)
        def sql = "select count(1) count ,city_id city from estate where city_id is not null group by city_id"
        def result = db.rows(sql).asList()
        Map<String,String> map = new HashMap<String,String>()
        result.each{
            map.put(it?.city?.id,it?.count)
        }

        Community.executeQuery("from Community").each {
            println it?.id+"--"+it?.communityScore
            //start
            println "计算小区评分"
            def score = scoreApiService.communityLiquidityScore(it?.communityId.toString())
            //查询权值
            def communityScoreWeight = CommunityScoreWeight.list().get(0)

            def closingWeight = communityScoreWeight.closingWeight
            // 成交率权重
            def listingWeight = communityScoreWeight.listingWeight
            // 挂牌率权重
            def dealAvgDayWeight = communityScoreWeight.dealAvgDayWeight
            // 成交周期权重
            def discountrateWeight = communityScoreWeight.discountrateWeight
            // 折价比权重
            def foreclosureTimesWeight = communityScoreWeight.foreclosureTimesWeight
            // 法拍次数权重

            //小区配套权值
            def ifSchoolZoneScoreWeight = communityScoreWeight.schoolDistrictsWeight
            def communityTrafficScoreWeight = communityScoreWeight.trafficWeight
            def houseAgeScoreWeight = communityScoreWeight.houseAgeWeight
            def communityHospitalScoreWeight = communityScoreWeight.hospitalWeight
            def communityMallScoreWeight = communityScoreWeight.mallWeight
            def communityGreeningrateScoreWeight = communityScoreWeight.afforestationWeight
            def communityPlotratioScoreWeight = communityScoreWeight.ratioWeight
            def communityParkScoreWeight = communityScoreWeight.parkWeight
            def communityPmfeeScoreWeight = communityScoreWeight.propertyFeeWeight
            def communitySupermarketScoreWeight = communityScoreWeight.superMarketWeight
            def communityBankScoreWeight = communityScoreWeight.bankWeight

            def scenicWeight = communityScoreWeight.scenicWeight
            def noisePullutionWeight = communityScoreWeight.noisePullutionWeight
            def airPullutionWeight = communityScoreWeight.airPullutionWeight

            //小区总分
            def liquidWeight = communityScoreWeight.liquidityWeight
            def surroundWeight = communityScoreWeight.assortWeight
            def natureWeight = communityScoreWeight.natureWeight

            //小区配套评分
            def ifSchoolZoneScore = 0
            def communityTrafficScore = 0
            def houseAgeScore = 0
            def communityHospitalScore = 0
            def communityMallScore = 0
            def communityGreeningrateScore = 0
            def communityPlotratioScore = 0
            def communityParkScore = 0
            def communityPmfeeScore = 0
            def communitySupermarketScore = 0
            def communityBankScore = 0

            //流动性评分
            def closingScore = 0
            def dealAvgDayScore = 0
            def listingScore = 0
            def discountrateScore = 0
            def foreclosureTimesScore = 0

            def scenicScore = 0
            def noisePullutionScore = 0
            def airPullutionScore = 0

            //小区配套总分
            def communitySurroundingScore = 0

            //小区流动性总分
            def liquidityScore = 0

            //小区自然总分
            def natureScore = 0

            def scoreArr = []
            def surroudArr = []
            def natureArr = []

            if (score?.closingScore)
            {
                //成交率评分
                closingScore = (score?.closingScore ? score?.closingScore : 0) * closingWeight
                //成交周期评分
                dealAvgDayScore = (score?.dealAverageDayScore ? score?.dealAverageDayScore : 0) * dealAvgDayWeight
                //挂牌率评分
                listingScore = (score?.listingScore ? score?.listingScore : 0) * listingWeight
                //折价比例评分（法拍计算）
                discountrateScore = (score?.discountrateScore ? score?.discountrateScore : 0) * discountrateWeight
                //法拍次数评分
                foreclosureTimesScore = (score?.foreclosureTimesScore ? score?.foreclosureTimesScore : 0) * foreclosureTimesWeight

                ifSchoolZoneScore = (score?.ifSchoolZoneScore ? score?.ifSchoolZoneScore : 0) * ifSchoolZoneScoreWeight
                communityTrafficScore = (score?.communityTrafficScore ? score?.communityTrafficScore : 0) * communityTrafficScoreWeight
                houseAgeScore = (score?.houseAgeScore ? score?.houseAgeScore : 0) * houseAgeScoreWeight
                communityHospitalScore = (score?.communityHospitalScore ? score?.communityHospitalScore : 0) * communityHospitalScoreWeight
                communityMallScore = (score?.communityMallScore ? score?.communityMallScore : 0) * communityMallScoreWeight
                communityGreeningrateScore = (score?.communityGreeningrateScore ? score?.communityGreeningrateScore : 0) * communityGreeningrateScoreWeight
                communityPlotratioScore = (score?.communityPlotratioScore ? score?.communityPlotratioScore : 0) * communityPlotratioScoreWeight
                communityParkScore = (score?.communityParkScore ? score?.communityParkScore : 0) * communityParkScoreWeight
                communityPmfeeScore = (score?.communityPmfeeScore ? score?.communityPmfeeScore : 0) * communityPmfeeScoreWeight
                communitySupermarketScore = (score?.communitySupermarketScore ? score?.communitySupermarketScore : 0) * communitySupermarketScoreWeight
                communityBankScore = (score?.communityBankScore ? score?.communityBankScore : 0) * communityBankScoreWeight

                scenicScore = (score?.communityRecentlyScenicScore ? score?.communityRecentlyScenicScore : 0) * scenicWeight
                noisePullutionScore = (score?.communityRecentlySubwayScore ? score?.communityRecentlySubwayScore : 0) * noisePullutionWeight
                airPullutionScore = (score?.communityRecentlyPollutionScore ? score?.communityRecentlyPollutionScore : 0) * airPullutionWeight

                communitySurroundingScore = ifSchoolZoneScore + communityTrafficScore + houseAgeScore + communityHospitalScore + communityMallScore + communityGreeningrateScore + communityPlotratioScore + communityParkScore + communityPmfeeScore + communitySupermarketScore + communityBankScore

                liquidityScore = closingScore + dealAvgDayScore + listingScore + discountrateScore + foreclosureTimesScore

                natureScore = scenicScore + noisePullutionScore + airPullutionScore

            }
            def communityScore = liquidityScore * liquidWeight + communitySurroundingScore * surroundWeight + natureScore * natureWeight
            //end

            //start
            println "计算押品集中度"
            //算出该小区押品数量
            def c1 = Estate.countByCommunityId(it?.communityId)
            //该城市所有押品数量 相处
            def c2 =  map.get(it?.city?.id) ? map.get(it?.city?.id) : 0
            println c1+"--"+c2
            def ratio = 0
            if(c1 && c2){
                ratio = -1666.7*(c1/c2) + 5.7
            }
            //end
            println "communityScore:"+communityScore
            println "liquidityScore:"+liquidityScore
            println "ratio"+ratio
            //综合风险评分
            def finalScore =0.4 * ratio + 0.33 * liquidityScore + 0.27 * communityScore
            println "finalScore:"+finalScore
            it.concentrationRatio = finalScore
            it?.save(flush:true)

            //生成预警预警
                if(finalScore <= 3.5){
                    println "触发预警"
                    def type = RiskWarningTypeDict.findByCode("7")
                    def status = RiskWarningStatusDict.findByCode("2")
                    def riskWarning = RiskWarning.findByCommunityAndType(it, type)
                    if (!riskWarning)
                    {
                        riskWarning = new RiskWarning()
                    }
                    riskWarning.type = type
                    riskWarning.community = it
                    riskWarning.status = status
                    if (riskWarning.validate())
                    {
                        riskWarning.save()
                    }
                    else
                    {
                        println riskWarning.errors
                    }
                }

            println "end"
        }

        render "处理完成"
    }

    @Transactional
    def save(Community community) {
        if (community == null) {
            transactionStatus.setRollbackOnly()
            notFound()
            return
        }

        if (community.hasErrors()) {
            transactionStatus.setRollbackOnly()
            respond community.errors, view:'create'
            return
        }

        community.save flush:true

        request.withFormat {
            form multipartForm {
                flash.message = message(code: 'default.created.message', args: [message(code: 'community.label', default: 'Community'), community.id])
                redirect community
            }
            '*' { respond community, [status: CREATED] }
        }
    }

    def edit(Community community) {
        respond community
    }

    @Transactional
    def update(Community community) {
        if (community == null) {
            transactionStatus.setRollbackOnly()
            notFound()
            return
        }

        if (community.hasErrors()) {
            transactionStatus.setRollbackOnly()
            respond community.errors, view:'edit'
            return
        }

        community.save flush:true

        request.withFormat {
            form multipartForm {
                flash.message = message(code: 'default.updated.message', args: [message(code: 'community.label', default: 'Community'), community.id])
                redirect community
            }
            '*'{ respond community, [status: OK] }
        }
    }

    @Transactional
    def delete(Community community) {

        if (community == null) {
            transactionStatus.setRollbackOnly()
            notFound()
            return
        }

        community.delete flush:true

        request.withFormat {
            form multipartForm {
                flash.message = message(code: 'default.deleted.message', args: [message(code: 'community.label', default: 'Community'), community.id])
                redirect action:"index", method:"GET"
            }
            '*'{ render status: NO_CONTENT }
        }
    }

    protected void notFound() {
        request.withFormat {
            form multipartForm {
                flash.message = message(code: 'default.not.found.message', args: [message(code: 'community.label', default: 'Community'), params.id])
                redirect action: "index", method: "GET"
            }
            '*'{ render status: NOT_FOUND }
        }
    }
}
